<?php
/**
 * Simple Controller implementation.
 * @package halo
 */

hc_core_ClassLoader::load('halo_IController');

/**
 * Simple Controller implementation.
 *
 * Very simple controller. Supports generating model data and handling POST method.
 * A simple subclass could look like this:
 *
 * <code>
 * class FooController extends halo_SimpleController {
 *     private $isPost = false;
 *     protected function doPost($httpRequest, $httpResponse) {
 *         $this->isPost = true;
 *         return null;
 *     }
 *     protected function generateModel($httpRequest, $httpResponse) {
 *         $model = parent::generateModel($httpRequest, $httpResponse);
 *         $model['hello'] = 'world';
 *         $model['isPost'] = $this->isPost
 *     }
 * }
 * </code>
 *
 * Please note this is for example only. It would not be wise to store
 * something like isPost in an instance variable. Again, this is only for show!
 * @package halo
 */
class halo_SimpleController implements halo_IController {

    /**
     * Name of view.
     * @var string
     */
    protected $view;

    /**
     * Gets the name of the view.
     * @return string View name.
     */
    public function getView() {
        return $this->view;
    }

    /**
     * Sets the name of the view.
     * @param string $view View name.
     */
    public function setView($view) {
        $this->view = $view;
    }

    /**
     * Handle request.
     *
     * If the request method is POST, the {@link $view} is set to the return value of
     * {@link doPost()} (If doPost() returns NULL, the view stays set to the default
     * view name). The model is set to the return value of {@link generateModel()}.
     * Returns a {@link halo_ModelAndView} using these values.
     *
     * @param halo_HttpRequest $httpRequest The request.
     * @param halo_HttpResponse $httpResponse The response.
     * @return halo_ModelAndView Model and View or NULL if output has already been taken care of.
     */
    final public function handleRequest(halo_HttpRequest $httpRequest, halo_HttpResponse $httpResponse) {
        $this->initRequest($httpRequest, $httpResponse);
        if ( $httpRequest->isPostMethod() ) {
            $postView = $this->doPost($httpRequest, $httpResponse);
            if ( $postView !== null ) {
                $this->view = $postView;
            }
        }
        $model = $this->generateModel($httpRequest, $httpResponse);
        return new halo_ModelAndView($this->view, $model);
    }

    /**
     * Initialize the request.
     *
     * Called by the {@link handleRequest} workflow in all cases.
     *
     * If there is any state that needs to be setup and shared between
     * doPost() and generateModel(), it can be handled here.
     *
     * Subclasses should always reference the parent::initRequest().
     * @param halo_HttpRequest $httpRequest The request.
     * @param halo_HttpResponse $httpResponse The response.
     */
    protected function initRequest(halo_HttpRequest $httpRequest, halo_HttpResponse $httpResponse) {
    }

    /**
     * Generate the model.
     *
     * Called by the {@link handleRequest} workflow in all cases.
     *
     * Subclasses should always reference the parent::generateModel().
     * @param halo_HttpRequest $httpRequest The request.
     * @param halo_HttpResponse $httpResponse The response.
     * @return array Model.
     */
    protected function generateModel(halo_HttpRequest $httpRequest, halo_HttpResponse $httpResponse) {
        return array();
    }

    /**
     * Do something on POST.
     *
     * Called by the {@link handleRequest} workflow in the event that the HTTP Request
     * was a POST method.
     * Subclasses should always reference the parent::generateModel().
     * @param halo_HttpRequest $httpRequest The request.
     * @param halo_HttpResponse $httpResponse The response.
     * @return string View name or NULL if view name should be the default view name.
     */
    protected function doPost(halo_HttpRequest $httpRequest, halo_HttpResponse $httpResponse) {
        return null;
    }
}
?>
